// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
; (function ($, window, document, undefined) {
  
  "use strict";
  
  // Create the defaults once
  var pluginName = "simpleCalendar",
  defaults = {
    months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], //string of months starting from january
    days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], //string of days starting from sunday
    displayYear: true, // display year in header
    fixedStartDay: true, // Week begin always by monday or by day set by number 0 = sunday, 7 = saturday, false = month always begin by first day of the month
    displayEvent: true, // display existing event
    disableEventDetails: false, // disable showing event details
    disableEmptyDetails: false, // disable showing empty date details
    events: [], // List of event
    onInit: function (calendar) { }, // Callback after first initialization
    onMonthChange: function (month, year) { }, // Callback on month change
    onDateSelect: function (date, events) { }, // Callback on date selection
    onEventSelect: function () { },              // Callback fired when an event is selected     - see $(this).data('event')
    onEventCreate: function ($el) { },          // Callback fired when an HTML event is created - see $(this).data('event')
    onDayCreate: function ($el, d, m, y) { }  // Callback fired when an HTML day is created   - see $(this).data('today'), .data('todayEvents')
  };
  
  // The actual plugin constructor
  function Plugin(element, options) {
    this.element = element;
    this.settings = $.extend({}, defaults, options);
    this._defaults = defaults;
    this._name = pluginName;
    this.currentDate = new Date();
    this.init();
  }
  
  // Avoid Plugin.prototype conflicts
  $.extend(Plugin.prototype, {
    init: function () {
      var container = $(this.element);
      var todayDate = this.currentDate;
      var calendar = $('<div class="calendar"></div>');
      var header = $('<header>' +
      '<div class="header-left">' +
      '<a class="simple-calendar-btn btn-prev" href="#"><i class="fa-solid fa-chevron-left"></i></a>' +
      '<h2 class="month"></h2>' +
      '<a class="simple-calendar-btn btn-next" href="#"><i class="fa-solid fa-chevron-right"></i></a>' +
      '</div>' +
      '<div class="header-right">' +
      '<ul class="list-menu">' +
      '<li><a class="toggler" href="#">All Access</a>' +
      '<ul class="sub-menu">' +
      '<li><a href="#">All Access</a></li>' +
      '<li><a href="#">Public</a></li>' +
      '<li><a href="#">Private</a></li>' +
      '<li><a href="#">Community</a></li>' +
      '</ul>' +
      '</li>' +
      '<li><a class="toggler" href="#">All Block Chain</a>' +
      '<ul class="sub-menu">' +
      '<li><a href="#"><img src="assets/images/project/previous-image.png" alt="icon">Binance</a></li>' +
      '<li><a href="#"><img src="assets/images/project/previous-image2.png" alt="icon">Ethereum (ETH)</a></li>' +
      '<li><a href="#"><img src="assets/images/project/previous-image3.png" alt="icon">Polygon</a></li>' +
      '<li><a href="#"><img src="assets/images/project/chain.png" alt="icon">All Block Chain</a></li>' +
      '</ul>' +
      '</li>' +
      '</ul>' +
      '</div>' +
      '</header>');
      this.updateHeader(todayDate, header);
      calendar.append(header);
      
      this.buildCalendar(todayDate, calendar);
      container.append(calendar);
      
      this.bindEvents();
      this.settings.onInit(this);
    },
    
    //Update the current month header
    updateHeader: function (date, header) {
      var monthText = this.settings.months[date.getMonth()];
      monthText += this.settings.displayYear ? '<div class="year">' + ' ' + date.getFullYear() : '</div>';
      header.find('.month').html(monthText);
    },
    
    //Build calendar of a month from date
    buildCalendar: function (fromDate, calendar) {
      var plugin = this;
      
      calendar.find('table').remove();
      
      var body = $('<table></table>');
      var thead = $('<thead class="day-names"></thead>');
      var tbody = $('<tbody></tbody>');
      
      //setting current year and month
      var y = fromDate.getFullYear(), m = fromDate.getMonth();
      
      //first day of the month
      var firstDay = new Date(y, m, 1);
      //last day of the month
      var lastDay = new Date(y, m + 1, 0);
      // Start day of weeks
      var startDayOfWeek = firstDay.getDay();
      
      if (this.settings.fixedStartDay !== false) {
        // Backward compatibility
        startDayOfWeek = this.settings.fixedStartDay === true ? 1 : this.settings.fixedStartDay;
        
        // If first day of month is different of startDayOfWeek
        while (firstDay.getDay() !== startDayOfWeek) {
          firstDay.setDate(firstDay.getDate() - 1);
        }
        // If last day of month is different of startDayOfWeek + 7
        while (lastDay.getDay() !== ((startDayOfWeek + 6) % 7)) {
          lastDay.setDate(lastDay.getDate() + 1);
        }
      }
      
      //Header day in a week ( (x to x + 7) % 7 to start the week by monday if x = 1)
      for (var i = startDayOfWeek; i < startDayOfWeek + 7; i++) {
        thead.append($('<td>' + this.settings.days[i % 7].substring(0, 3) + '</td>'));
      }
      
      //For firstDay to lastDay
      for (var day = firstDay; day <= lastDay; day.setDate(day.getDate())) {
        var tr = $('<tr></tr>');
        //For each row
        for (var i = 0; i < 7; i++) {
          
          var td = $('<td><div class="day" data-date="' + day.toISOString() + '">' + day.getDate() + '</div></td>');
          
          var $day = td.find('.day');
          
          //if today is this day
          if (day.toDateString() === (new Date).toDateString()) {
            $day.addClass("today");
          }
          
          //if day is not in this month
          if (day.getMonth() != fromDate.getMonth()) {
            $day.addClass("wrong-month");
          }
          
          // filter today's events
          var todayEvents = plugin.getDateEvents(day);
          var star = '*';
          var eventImg;
          if (todayEvents.length && plugin.settings.displayEvent) {
            $day.addClass(plugin.settings.disableEventDetails ? "has-event disabled" : "has-event");
            if (plugin.getDateEvents(day).length <= 1) {
              
              let event = plugin.getDateEvents(day)[0];
              eventImg = '<img src="' + event.image + '" data-id="' + event.id + '" data-name="' + event.name + '" data-img="' + event.image + '" data-sdate="' + event.startDate + '" data-edate="' + event.endDate + '" data-price="' + event.price + '" data-raise="' + event.raise + '" data-duration="' + event.duration + '" data-access="' + event.access + '" data-minallocation="' + event.minallocation + '" data-maxallocation="' + event.maxallocation + '" data-telegram="' + event.telegram + '" data-facebook="' + event.facebook + '" data-twitter="' + event.twitter + '" data-web="' + event.web + '" class="eventShowImg" title="' + event.name + '" data-bs-toggle="modal" data-bs-target="#eventModal"/>';
              td.append(eventImg);
            }
          } else {
            $day.addClass(plugin.settings.disableEmptyDetails ? "disabled" : "");
          }
          // associate some data available from the onDayCreate callback
          $day.data('todayEvents', todayEvents);
          
          // simplify further customization
          this.settings.onDayCreate($day, day.getDate(), m, y);
          var dayss = plugin.getDateEvents(day);
          var eventLength = dayss.length;
          if (eventLength > 1) {
            // td.append(star);
            dayss.forEach(event => {
              // console.log(event.image);
              eventImg = '<img src="' + event.image + '" data-id="' + event.id + '" data-name="' + event.name + '" data-img="' + event.image + '" data-sdate="' + event.startDate + '" data-edate="' + event.endDate + '" data-price="' + event.price + '" data-raise="' + event.raise + '" data-duration="' + event.duration + '" data-access="' + event.access + '" data-minallocation="' + event.minallocation + '" data-maxallocation="' + event.maxallocation + '" data-telegram="' + event.telegram + '" data-facebook="' + event.facebook + '" data-twitter="' + event.twitter + '" data-web="' + event.web + '" class="eventShowImg" title="' + event.name + '" data-bs-toggle="modal" data-bs-target="#eventModal"/>';
              td.append(eventImg);
              // td.append('**');
            });
          }
          // console.log(td)
          tr.append(td);
          day.setDate(day.getDate() + 1);
        }
        tbody.append(tr);
      }
      body.append(thead);
      body.append(tbody);
      var eventContainer = $('<div class="event-container"><div class="event-wrapper"></div></div>');
      // var eventContainer = $('<div class="event-container"><div class="close"></div><div class="event-wrapper"></div></div>');
      calendar.append(body);
      calendar.append(eventContainer);
    },
    
    changeMonth: function (value) {
      this.currentDate.setMonth(this.currentDate.getMonth() + value, 1);
      this.buildCalendar(this.currentDate, $(this.element).find('.calendar'));
      this.updateHeader(this.currentDate, $(this.element).find('.calendar header'));
      this.settings.onMonthChange(this.currentDate.getMonth(), this.currentDate.getFullYear())
    },
    //Init global events listeners
    bindEvents: function () {
      var plugin = this;
      
      //Remove previously created events
      $(plugin.element).off();
      
      //Click previous month
      $(plugin.element).on('click', '.btn-prev', function (e) {
        plugin.changeMonth(-1)
        e.preventDefault();
      });
      
      //Click next month
      $(plugin.element).on('click', '.btn-next', function (e) {
        plugin.changeMonth(1);
        e.preventDefault();
      });
      
      // Binding day event
      $(plugin.element).on('click', '.day', function (e) {
        var date = new Date($(this).data('date'));
        var events = plugin.getDateEvents(date);
        if (!$(this).hasClass('disabled')) {
          plugin.fillUp(e.pageX, e.pageY);
          plugin.displayEvents(events);
        }
        // plugin.settings.onDateSelect(date, events);
      });
      
      //Binding event container close
      $(plugin.element).on('click', '.event-container .close', function (e) {
        plugin.empty(e.pageX, e.pageY);
      });
    },
    displayEvents: function (events) {
      var plugin = this;
      // var container = $(this.element).find('.event-wrapper');
      var elem = $(plugin.element);
      events.forEach(function (event) {
        console.log(event);
        // alert(JSON.stringify(event));
        return event;
        // Event Card
      })
    },
    addEvent: function (newEvent) {
      var plugin = this;
      // add the new event to events list
      plugin.settings.events = [...plugin.settings.events, newEvent]
      this.buildCalendar(this.currentDate, $(this.element).find('.calendar'));
    },
    setEvents: function (newEvents) {
      var plugin = this;
      // add the new event to events list
      plugin.settings.events = newEvents
      this.buildCalendar(this.currentDate, $(this.element).find('.calendar'));
    },
    //Small effect to fillup a container
    fillUp: function (x, y) {
      var plugin = this;
      var elem = $(plugin.element);
      var elemOffset = elem.offset();
      
      var filler = $('<div class="filler" style=""></div>');
      filler.css("left", x - elemOffset.left);
      filler.css("top", y - elemOffset.top);
      
      elem.find('.calendar').append(filler);
      
      filler.animate({
        width: "100px",
        height: "100px"
      }, 100, function () {
        // elem.find('.event-container').show();
        filler.hide();
      });
    },
    //Small effect to empty a container
    empty: function (x, y) {
      var plugin = this;
      var elem = $(plugin.element);
      var elemOffset = elem.offset();
      
      var filler = elem.find('.filler');
      filler.css("width", "100px");
      filler.css("height", "100px");
      
      filler.show();
      
      elem.find('.event-container').hide().find('.event').remove();
      
      filler.animate({
        width: "0%",
        height: "0%"
      }, 500, function () {
        filler.remove();
      });
    },
    getDateEvents: function (d) {
      var plugin = this;
      return plugin.settings.events.filter(function (event) {
        return plugin.isDayBetween(new Date(d), new Date(event.startDate), new Date(event.endDate));
      });
    },
    isDayBetween: function (d, dStart, dEnd) {
      dStart.setHours(0, 0, 0);
      dEnd.setHours(23, 59, 59, 999);
      d.setHours(12, 0, 0);
      
      return dStart <= d && d <= dEnd;
    },
    formatDateEvent: function (dateStart, dateEnd) {
      var formatted = '';
      formatted += this.settings.days[dateStart.getDay()] + ' - ' + dateStart.getDate() + ' ' + this.settings.months[dateStart.getMonth()].substring(0, 3);
      
      if (dateEnd.getDate() !== dateStart.getDate()) {
        formatted += ' to ' + dateEnd.getDate() + ' ' + this.settings.months[dateEnd.getMonth()].substring(0, 3)
      }
      return formatted;
    }
  });
  
  // A really lightweight plugin wrapper around the constructor,
  // preventing against multiple instantiations
  $.fn[pluginName] = function (options) {
    return this.each(function () {
      if (!$.data(this, "plugin_" + pluginName)) {
        $.data(this, "plugin_" + pluginName, new Plugin(this, options));
      }
    });
  };
})(jQuery, window, document);
